home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / ada / gnat-3.05- / gnat-3 / gnat-3.05-i486-linux-elf-bin / rts / a-sysdep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-07  |  12.6 KB  |  358 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                         GNAT COMPILER COMPONENTS                         */
  4. /*                                                                          */
  5. /*                              A - S Y S D E P                             */
  6. /*                                                                          */
  7. /*                          C Implementation File                           */
  8. /*                                                                          */
  9. /*                            $Revision: 1.16 $                             */
  10. /*                                                                          */
  11. /*   Copyright (C) 1992,1993,1994,1995,1996 Free Software Foundation, Inc.  */
  12. /*                                                                          */
  13. /* GNAT is free software;  you can  redistribute it  and/or modify it under */
  14. /* terms of the  GNU General Public License as published  by the Free Soft- */
  15. /* ware  Foundation;  either version 2,  or (at your option) any later ver- */
  16. /* sion.  GNAT is distributed in the hope that it will be useful, but WITH- */
  17. /* OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY */
  18. /* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License */
  19. /* for  more details.  You should have  received  a copy of the GNU General */
  20. /* Public License  distributed with GNAT;  see file COPYING.  If not, write */
  21. /* to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, */
  22. /* MA 02111-1307, USA.                                                      */
  23. /*                                                                          */
  24. /* As a  special  exception,  if you  link  this file  with other  files to */
  25. /* produce an executable,  this file does not by itself cause the resulting */
  26. /* executable to be covered by the GNU General Public License. This except- */
  27. /* ion does not  however invalidate  any other reasons  why the  executable */
  28. /* file might be covered by the  GNU Public License.                        */
  29. /*                                                                          */
  30. /* GNAT was originally developed  by the GNAT team at  New York University. */
  31. /* It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). */
  32. /*                                                                          */
  33. /****************************************************************************/
  34.  
  35. /* This file contains system dependent symbols that are referenced in the
  36.    GNAT Run Time Library */
  37.  
  38. #include "config.h"
  39.  
  40. #ifdef WINNT
  41. #include <fcntl.h>
  42. #include <sys/types.h>
  43. #include <sys/stat.h>
  44. #include <errno.h>
  45. #endif
  46.  
  47. #include <stdio.h>
  48.  
  49. /*
  50.    mode_read_text
  51.    open text file for reading
  52.    rt for DOS and Windows NT, r for Unix
  53.  
  54.    mode_write_text
  55.    truncate to zero length or create text file for writing
  56.    wt for DOS and Windows NT, w for Unix
  57.  
  58.    mode_append_text
  59.    append; open or create text file for writing at end-of-file
  60.    at for DOS and Windows NT, a for Unix
  61.  
  62.    mode_read_binary
  63.    open binary file for reading
  64.    rb for DOS and Windows NT, r for Unix
  65.  
  66.    mode_write_binary
  67.    truncate to zero length or create binary file for writing
  68.    wb for DOS and Windows NT, w for Unix
  69.  
  70.    mode_append_binary
  71.    append; open or create binary file for writing at end-of-file
  72.    ab for DOS and Windows NT, a for Unix
  73.  
  74.    mode_read_text_plus
  75.    open text file for update (reading and writing)
  76.    r+t for DOS and Windows NT, r+ for Unix
  77.  
  78.    mode_write_text_plus
  79.    truncate to zero length or create text file for update
  80.    w+t for DOS and Windows NT, w+ for Unix
  81.  
  82.    mode_append_text_plus
  83.    append; open or create text file for update, writing at end-of-file
  84.    a+t for DOS and Windows NT, a+ for Unix
  85.  
  86.    mode_read_binary_plus
  87.    open binary file for update (reading and writing)
  88.    r+b for DOS and Windows NT, r+ for Unix
  89.  
  90.    mode_write_binary_plus
  91.    truncate to zero length or create binary file for update
  92.    w+b for DOS and Windows NT, w+ for Unix
  93.  
  94.    mode_append_binary_plus
  95.    append; open or create binary file for update, writing at end-of-file
  96.    a+b for DOS and Windows NT, a+ for Unix
  97.  
  98.    Notes:
  99.  
  100.    (1) Opening a file with read mode fails if the file does not exist or
  101.    cannot be read.
  102.  
  103.    (2) Opening a file with append mode causes all subsequent writes to the
  104.    file to be forced to the then current end-of-file, regardless of
  105.    intervening calls to the fseek function.
  106.  
  107.    (3) When a file is opened with update mode, both input and output may be
  108.    performed on the associated stream.  However, output may not be directly
  109.    followed by input without an intervening call to the fflush function or
  110.    to a file positioning function (fseek, fsetpos, or rewind), and input
  111.    may not be directly followed by output without an intervening call to a
  112.    file positioning function, unless the input operation encounters
  113.    end-of-file.
  114.  
  115.    The other target dependent declarations here are for the two functions
  116.    set_binary_mode and set_text_mode:
  117.  
  118.       void set_binary_mode (int handle);
  119.       void set_text_mode   (int handle);
  120.  
  121.    These functions have no effect in Unix (or similar systems where there is
  122.    no distinction between binary and text files), but in DOS (and similar
  123.    systems where text mode does CR/LF translation), these functions allow
  124.    the mode of the stream with the given handle (fileno can be used to get
  125.    the handle of a stream) to be changed dynamically. The returned result
  126.    is 0 if no error occurs and -1 if an error occurs.
  127.  
  128.    Finally there is a boolean (character) variable
  129.  
  130.       char text_translation_required;
  131.  
  132.    which is zero (false) in Unix mode, and one (true) in DOS mode, with a
  133.    true value indicating that text translation is required on text files
  134.    and that fopen supports the trailing t and b modifiers.
  135.  
  136. */
  137.  
  138. #if defined(WINNT) || defined (MSDOS) || defined (__EMX__)
  139.  
  140.   const char *mode_read_text = "rt";
  141.   const char *mode_write_text = "wt";
  142.   const char *mode_append_text = "at";
  143.   const char *mode_read_binary = "rb";
  144.   const char *mode_write_binary = "wb";
  145.   const char *mode_append_binary = "ab";
  146.   const char *mode_read_text_plus = "r+t";
  147.   const char *mode_write_text_plus = "w+t";
  148.   const char *mode_append_text_plus = "a+t";
  149.   const char *mode_read_binary_plus = "r+b";
  150.   const char *mode_write_binary_plus = "w+b";
  151.   const char *mode_append_binary_plus = "a+b";
  152.   const char text_translation_required = 1;
  153.  
  154.   /* for now these functions do nothing, must be fixed later ??? */
  155.   void set_binary_mode (int handle) { ; }
  156.   void set_text_mode   (int handle) { ; }
  157.  
  158. #else
  159.   const char *mode_read_text = "r";
  160.   const char *mode_write_text = "w";
  161.   const char *mode_append_text = "a";
  162.   const char *mode_read_binary = "r";
  163.   const char *mode_write_binary = "w";
  164.   const char *mode_append_binary = "a";
  165.   const char *mode_read_text_plus = "r+";
  166.   const char *mode_write_text_plus = "w+";
  167.   const char *mode_append_text_plus = "a+";
  168.   const char *mode_read_binary_plus = "r+";
  169.   const char *mode_write_binary_plus = "w+";
  170.   const char *mode_append_binary_plus = "a+";
  171.   const char text_translation_required = 0;
  172.  
  173.   /* these functions do nothing in non-DOS systems */
  174.   void set_binary_mode (FILE *stream) { ; }
  175.   void set_text_mode   (FILE *stream) { ; }
  176.  
  177. #endif
  178.  
  179. #if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
  180.     || defined (__osf__)
  181. #include <termios.h>
  182. #include <fcntl.h>
  183. #endif
  184.  
  185. /* Implements the common processing for getc_immediate and
  186.    getc_immediate_nowait. */
  187. void
  188. getc_immediate_common
  189.   (FILE *stream, int *ch, int *end_of_file, int *avail, int waiting);
  190.  
  191. /* Called by Get_Immediate (Foo); */
  192. void
  193. getc_immediate
  194.   (FILE *stream, int *ch, int *end_of_file)
  195. {
  196.   int avail;
  197.   getc_immediate_common (stream, ch, end_of_file, &avail, 1);
  198. }
  199.  
  200. /* Called by Get_Immediate (Foo, Available); */
  201. void
  202. getc_immediate_nowait
  203.   (FILE *stream, int *ch, int *end_of_file, int *avail)
  204. {
  205.   getc_immediate_common (stream, ch, end_of_file, avail, 0);
  206. }
  207.  
  208. /* Called by getc_immediate () and getc_immediate_nowait () */
  209. void
  210. getc_immediate_common
  211.   (FILE *stream, int *ch, int *end_of_file, int *avail, int waiting)
  212. {
  213. #if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
  214.     || defined (__osf__)
  215.   char c;
  216.   int nread;
  217.   int flags;
  218.   int good_one = 0;
  219.   int eof_ch = 4; /* Ctrl-D */
  220.   int fd = fileno (stream);
  221.   struct termios otermios_rec, termios_rec;
  222.  
  223.   if (isatty (fd))
  224.     {
  225.       tcgetattr (fd, &termios_rec);
  226.       memcpy (&otermios_rec, &termios_rec, sizeof (struct termios));
  227.       while (!good_one)
  228.         {
  229.           /* Set RAW mode */
  230.           termios_rec.c_lflag = termios_rec.c_lflag & ~ICANON;
  231. #if defined(sgi) || defined (sun) || defined (__EMX__) || defined (__osf__)
  232.           /* If waiting (i.e. Get_Immediate (Char)), set MIN = 1 and wait for
  233.              a character forever. This doesn't seem to effect Ctrl-Z or
  234.              Ctrl-C processing except on OS/2 where Ctrl-C won't work right
  235.              unless we do a read loop. Luckily we can delay a bit between
  236.              iterations. If not waiting (i.e. Get_Immediate (Char, Available)),
  237.              don't wait for anything but timeout immediately. */
  238. #ifdef __EMX__
  239.           termios_rec.c_cc[VMIN] = 0;
  240.           termios_rec.c_cc[VTIME] = waiting;
  241. #else
  242.           termios_rec.c_cc[VMIN] = waiting;
  243.           termios_rec.c_cc[VTIME] = 0;
  244. #endif
  245.           eof_ch = termios_rec.c_cc[VEOF];
  246. #endif
  247.           tcsetattr (fd, TCSANOW, &termios_rec);
  248.  
  249. #if defined (linux)
  250.           /* If we don't set this mode on Linux, Ctrl-C and Ctrl-Z processing
  251.              get messed up */
  252.           flags = fcntl (fd, F_GETFL);
  253.           fcntl (fd, F_SETFL, O_NONBLOCK | flags);
  254. #endif
  255.  
  256.           nread = fread (&c, 1, 1, stream);
  257.           if (nread > 0)
  258.             {
  259.               /* On Unix terminals, Ctrl-D (EOT) is an End of File. */
  260.               if (c == eof_ch)
  261.                 {
  262.                   *avail = 0;
  263.                   *end_of_file = 1;
  264.                   good_one = 1;
  265.                 }
  266.               /* Everything else is ok */
  267.               else if (c != eof_ch)
  268.                 {
  269.                   *avail = 1;
  270.                   *end_of_file = 0;
  271.                   good_one = 1;
  272.                 }
  273.               /* Stuff these characters back into the buffer, reset the
  274.                  terminal modes back to normal and let somebody else grab it
  275.                  I thought this might be necessary for Ctrl-C and Ctrl-Z
  276.                  processing by the shell to work, but evidently not.
  277.                  Keep it around just in case. */
  278.               else if (c != c)
  279.                 {
  280.                   good_one = 0;
  281.                   ungetc (c, stream);
  282. #if defined(linux)
  283.                   fcntl (fd, F_SETFL, flags);
  284. #endif
  285.                   tcsetattr (fd, TCSANOW, &otermios_rec);
  286.                 }
  287.             }
  288.           else if (!waiting)
  289.             {
  290.               *avail = 0;
  291.               *end_of_file = 0;
  292.               good_one = 1;
  293.             }
  294.           else
  295.             {
  296.               good_one = 0;
  297.             }
  298.         }
  299. #if defined(linux)
  300.       fcntl (fd, F_SETFL, flags);
  301. #endif
  302.       tcsetattr (fd, TCSANOW, &otermios_rec);
  303.       *ch = c;
  304.     }
  305.   else
  306. #endif
  307.     /* If we're not on a terminal, then we don't need any fancy processing */
  308.     /* Also this is the only thing that's left if we're not on one of the
  309.        supported systems. */
  310.     {
  311.       *ch = fgetc (stream);
  312.       if (feof (stream))
  313.         {
  314.           *end_of_file = 1;
  315.           *avail = 0;
  316.         }
  317.       else
  318.         {
  319.           *end_of_file = 0;
  320.           *avail = 1;
  321.         }
  322.     }
  323. }
  324.  
  325.  
  326. /* the following definitions are provided in NT to support Windows based
  327.    Ada programs */
  328.  
  329. #ifdef WINNT
  330.  
  331. #include <windows.h>                /* required for all Windows applications */
  332.  
  333. HANDLE hInstance_global;            /* current instance                      */
  334. HANDLE hPrevInstance_global;        /* previous instance            */
  335. LPSTR lpCmdLine_global;             /* command line                 */
  336. int nCmdShow_global;                /* show-window type (open/icon) */
  337.  
  338. extern int __argc;
  339. extern char **__argv;
  340. extern char **environ;
  341.  
  342. int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  343. HANDLE hInstance;                   /* current instance             */
  344. HANDLE hPrevInstance;               /* previous instance            */
  345. LPSTR lpCmdLine;                    /* command line                 */
  346. int nCmdShow;                       /* show-window type (open/icon) */
  347. {
  348.  
  349.   hInstance_global = hInstance;
  350.   hPrevInstance_global = hPrevInstance;
  351.   lpCmdLine_global = lpCmdLine;
  352.   nCmdShow_global = nCmdShow;
  353.  
  354.   return main (__argc, __argv);  /* Should return value from PostQuitMessage */
  355. }
  356.  
  357. #endif /* WINNT */
  358.